/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.autoupdate; import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; import java.util.ResourceBundle; import org.openide.modules.ModuleDescription; import org.openide.util.NbBundle; import org.openide.NotifyDescriptor; import org.openide.TopManager; /** Support class for checking dependencies between modules * * @author phrebejk * @version */ class DependencyChecker extends Object { /** The ResourceBundle */ private static final ResourceBundle bundle = NbBundle.getBundle( DependencyChecker.class ); /** Holds modules available for update */ Updates updates; /** DependencyChecker is a singleton */ DependencyChecker( Updates updates ) { this.updates = updates; } /** Gets collection of modules which have to be added to download list * if we have to add the toAddModule. */ Collection modulesToAdd( ModuleUpdate toAdd ) { Collection result = new ArrayList(); checkDependencies( toAdd.getRemoteModule(), result ); return result; } /** Gets collection of modules which we have to remove from download list * if we have to remove the toRemove module. */ Collection modulesToRemove( ModuleUpdate toRemove ) { Collection result = new ArrayList(); checkReverseDependencies( toRemove.getRemoteModule(), result ); return result; } /** Builds Collection with modules which should be added * into download list to satisfy module dependencies. */ boolean checkDependencies( ModuleDescription md, Collection result ) { // Get all module dependencies ModuleDescription.Dependency[] deps = md.getDependencies(); // Array values say if the dependency is satisfied or not boolean[] satisfied = new boolean [ deps.length ]; // All installed modules ModuleDescription[] installedModules = Updates.getInstalledModules(); ModuleDescription[] installedPatches = Updates.getInstalledPatches(); // For all dependencies for ( int j = 0; j < deps.length; j++ ) { String message = null; // The module depends on other module if ( deps[j].getType() == ModuleDescription.Dependency.TYPE_MODULE ) { boolean ok = false; // Try to figure out if the dependency is satisfied by installed modules for (int i = 0; i < installedModules.length; i++) { ok = checkModuleDependency ( deps[j], installedModules[i] ); if ( ok ) break; } if ( !ok ) { // Try to figure out if the dependency is satisfied by installed patches for (int i = 0; i < installedPatches.length; i++) { ok = checkModuleDependency ( deps[j], installedPatches[i] ); if ( ok ) break; } } // Dependency was not satisfied by other module let's try modules // available for download if ( !ok ) { Collection availableModules = updates.getModules(); Iterator it = updates.getModules().iterator(); while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); if ( ok ) { if ( !result.contains( mu ) ) { result.add( mu ); //checkDependencies( mu.getRemoteModule(), result ); } break; } } } if ( !ok ) satisfied[j] = false; else satisfied[j] = true; } // Module depends on specific version of IDE else if ( deps[j].getType() == ModuleDescription.Dependency.TYPE_IDE ) { // Try to figure out if the dependency is satisfied by installed ide if ( checkIdeDependency ( deps[j], IdeDescription.getIdeDescription() ) ) { satisfied[j] = true; } else { // Try to find suitable IDE between the modules Collection availableModules = updates.getModules(); Iterator it = updates.getModules().iterator(); boolean ok = false; while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); if ( ok ) { if ( !result.contains( mu ) ) { result.add( mu ); //checkDependencies( mu.getRemoteModule(), result ); } break; } } satisfied[j] = ok; } } } StringBuffer sb = new StringBuffer( 200 ); sb.append( bundle.getString( "MSG_NotSatisfied" ) + "MODULE :" + md.getCodeName() ); int notSatisfied = 0; // For all dependencies for ( int j = 0; j < deps.length; j++ ) { if ( !satisfied[j] ) { sb.append( deps[j] ); notSatisfied++; } } if ( notSatisfied == 0 ) return true; NotifyDescriptor.Message nd = new NotifyDescriptor.Message( sb.toString(), NotifyDescriptor.ERROR_MESSAGE ); TopManager.getDefault().notify( nd ); return false; } /** Builds Collection with modules which should be removed * from download list to satisfy module dependencies. */ boolean checkReverseDependencies( ModuleDescription module, Collection result ) { //ArrayList dependentModules = new ArrayList(); ModuleDescription[] installedModules = Updates.getInstalledModules(); ModuleDescription[] installedPatches = Updates.getInstalledPatches(); // All listed modules Collection availableModules = updates.getModules(); Iterator it = updates.getModules().iterator(); while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); //if ( !info.update() ) We have to check all modules // continue; ModuleDescription md = mu.getRemoteModule(); ModuleDescription.Dependency[] deps = md.getDependencies(); // All dependencies of module boolean moduleOk = true; for ( int j = 0; j < deps.length; j++ ) { if ( deps[j].getType() == ModuleDescription.Dependency.TYPE_MODULE && deps[j].getName().equals( module.getCodeName() ) ) { boolean ok = false; // Check if not satisfied by installed modules for (int k = 0; k < installedModules.length; k++) { ok = checkModuleDependency ( deps[j], installedModules[k] ); if ( ok ) break; } // Check if it is not stisfied by installed patches for (int k = 0; k < installedPatches.length; k++) { ok = checkModuleDependency ( deps[j], installedPatches[k] ); if ( ok ) break; } // The module has unsatisfied dependency we have to remove it if ( !ok ) { moduleOk = false; break; } } else if ( deps[j].getType() == ModuleDescription.Dependency.TYPE_IDE && deps[j].getName().equals( module.getCodeName() ) ) { //Check if not satisfied by installed IDE if ( !checkModuleDependency ( deps[j], IdeDescription.getIdeDescription() ) ) { moduleOk = false; break; } } } if ( !moduleOk ) { if ( ! result.contains( mu ) ) { result.add( mu ); //checkReverseDependencies( mu.getRemoteModule(), result ); } } } if ( result.size() == 0 ) return true; else { /* StringBuffer sb = new StringBuffer( dependentModules.size() * 60 + 100); sb.append( bundle.getString( "MSG_DependentModules" ) ); for( int i = 0; i < dependentModules.size(); i++ ) sb.append( ((ModuleAutoUpdater.ModuleUpdateInformation)dependentModules.get( i )).getName() ).append( "\n" ); NotifyDescriptor.Confirmation nd = new NotifyDescriptor.Confirmation( sb.toString(), bundle.getString( "CTL_DependentModules" ), NotifyDescriptor.OK_OPTION ); TopManager.getDefault().notify( nd ); if( nd.getValue().equals( NotifyDescriptor.YES_OPTION ) ) { for( int i = 0; i < dependentModules.size(); i++ ) ((ModuleAutoUpdater.ModuleUpdateInformation)dependentModules.get( i )).setUpdate( false ); return true; } else */ return false; } } /** Tests if the dependency on module is satisfied by the otherModule */ boolean checkModuleDependency ( ModuleDescription.Dependency dep, ModuleDescription otherModule ) { boolean satisfied = false; if ( dep.getName().equals (otherModule.getCodeName ())) { if ( dep.getComparison() == ModuleDescription.Dependency.COMPARE_ANY) { return true; } else if (dep.getComparison() == ModuleDescription.Dependency.COMPARE_SPEC) { try { if (otherModule.getSpecVersion () == null) return false; else if (! ModuleDescription.compatibleWith ( dep.getVersion(), otherModule.getSpecVersion ())) return false; else return true; } catch ( org.openide.modules.IllegalModuleException e ) { return false; } } else { // COMPARE_IMPL if (otherModule.getImplVersion () == null) return false; else if (! otherModule.getImplVersion ().equals (dep.getVersion())) return false; else return true; } } return false; } /** Tests dependency on the IDE */ boolean checkIdeDependency( ModuleDescription.Dependency dep, ModuleDescription ide ) { String IDEName = ide.getCodeName(); String IDESpecVersion = ide.getSpecVersion(); String IDEImplVersion = ide.getImplVersion(); // Not equal names if ( !IDEName.equals ( dep.getName() ) ) return false; //return ModuleDescription.getStringFormatted ("MSG_IDE_Name", name, IDEName); // NOI18N try { if ( dep.getComparison() == ModuleDescription.Dependency.COMPARE_SPEC ) { return ModuleDescription.compatibleWith (dep.getVersion(), IDESpecVersion); // ? null : ModuleDescription.getStringFormatted ("MSG_IDE_Spec", version, IDESpecVersion); // NOI18N } else if ( dep.getComparison() == ModuleDescription.Dependency.COMPARE_IMPL ) { return dep.getVersion().equals (IDEImplVersion); // ? null : ModuleDescription.getStringFormatted ("MSG_IDE_Impl", version, IDEImplVersion); // NOI18N } else { // COMPARE_ANY return true; } } catch ( org.openide.modules.IllegalModuleException e ) { return false; } } } /* * Log * 7 Gandalf 1.6 1/13/00 Petr Hrebejk i18 mk3 * 6 Gandalf 1.5 12/20/99 Petr Hrebejk Autocheck & security * finished * 5 Gandalf 1.4 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 4 Gandalf 1.3 10/8/99 Petr Hrebejk Next development version * 3 Gandalf 1.2 10/8/99 Petr Hrebejk Next Develop version * 2 Gandalf 1.1 10/7/99 Petr Hrebejk Next development version * 1 Gandalf 1.0 10/7/99 Petr Hrebejk * $ */